(function () {
    var animation_flag = false;//正在执行动画
    //计算加入事件队列的时刻，与执行延时函数的次数，相等时表示动画执行完毕
    var show_count = 0, deley_count = 0;
    var deley_space = 1000;//动画延时间隔
    var select = document.getElementById("select");
    var button = document.getElementById("button");
    var orderSelect = document.getElementById("order");
    var getArrDom = document.getElementById("getArr");
    var numberDom = document.getElementById("number");
    var deleyDom = document.getElementById("deley");

    //随机生成指定长度，固定区间的数组
    var random = function (n, max, min) {
        var arr = [];
        if (typeof max !== "number" || max < 100) {
            max = 100;
        }
        if (typeof min !== "number") {
            min = 0;
        }
        for (let i = 0; i < n; i++) {
            arr[i] = parseInt(Math.random() * (max - min + 1)) + min;
        }
        return arr;
    }
    //将数组用SVG显示数组
    var showArr = function (arr, m, n) {
        console.log(arr,m,n)
        var svg = document.getElementById("svg");
        var rectStr = "", textStr = "", lineStr = "";//矩形、文本和线的HTML字符串
        var height = svg.getAttribute("height"), width = svg.getAttribute("width");//画布宽高
        var rectWidth = 0, rectHeight = 0, spaceWidth = 0;//矩形宽度、间隔宽度
        var margin_level = 20, margin_veticle = 40;//水平、垂直边距
        var maxValue = 0;
        rectWidth = (width - margin_level * 2) / (arr.length) * 0.6;
        spaceWidth = rectWidth * 2 / 3;
        svg.innerHTML = "";

        var getMax = function (arr) {
            var max = 0;
            for (let i = 0; i < arr.length; i++) {
                if (max < arr[i]) {
                    max = arr[i];
                }
            }
            return max;
        }
        var getHeight = function (h) {
            return (height - 2 * margin_veticle) * (h / maxValue);
        }
        maxValue = getMax(arr);

        let arrGroup = []; // 存储分组信息
        let gapLegth = n - m;
        // 往前
        for (let i = m; i >= 0; i = i - gapLegth) {
            arrGroup.push(i);
        }
        // 往后
        for (let i = n; i < arr.length; i = i + gapLegth) {
            arrGroup.push(i);
        }

        //画线和数字
        for (let i = 0; i < arr.length; i++) {
            let cx = 0, cy = 0;//当前结点的定位像素坐标
            let groupColor = "#5CACEE";
            let color = "#CCCCCC";
            rectHeight = getHeight(arr[i]);
            cx = i * (spaceWidth + rectWidth) + margin_level;
            cy = height - rectHeight - margin_veticle;

            for(let j = 0; j < arrGroup.length; j++) {
                if(i === arrGroup[j] )
                color = "#5CACEE";
            }

            if (i === m) {
                color = "#FF3E96";
            } else if (i === n) {
                color = "#7CCD7C";
            }
            if (i === m && i === n) {
                color = "#EEC900";
            }
            var font_size = rectWidth / 2 > 20 ? 20 : rectWidth / 2
            rectStr += '<rect x="' + cx + '" y="' + cy + '" width="' + rectWidth + '" height="' + rectHeight + '" fill="' + color + '"/>';

            textStr += '<text x="' + (cx + rectWidth / 2) + '" y="' + (cy - 6) + '" fill="#171717"  style="font-size:' + font_size + 'pt;text-anchor: middle">' + arr[i] + '</text>';
            textStr += '<text x="' + (cx + rectWidth / 2) + '" y="' + (height - 25 + font_size) + '" fill="#171717"  style="font-size:' + font_size + 'pt;text-anchor: middle">' + (i + 1) + '</text>';
        }
        lineStr += '<line x1="0" y1="0" x2="0" y2="' + (height - 30) + '" style="stroke:#666;stroke-width:4" />'
            + '<line x1="0" y1="' + (height - margin_veticle + 10) + '" x2="' + width + '" y2="' + (height - margin_veticle + 10) + '" style="stroke:#666;stroke-width:2" />';
        svg.innerHTML = lineStr + rectStr + textStr;
    }
    //延时动画
    var showSort = function (arr, m, n) {
        var array = [];
        for (let i = 0; i < arr.length; i++) {
            array[i] = arr[i];
        }
        var callback = function (array, m, n) {
            animation_flag = true;
            showArr(array, m, n);
            deley_count++;
            if (deley_count >= show_count) {
                setTimeout(function () {
                    showArr(array);
                    animation_flag = false;//动画执行完毕
                    console.log("排序完成");
                    show_count = 0;
                    deley_count = 0;
                }, deley_space);
            }
        }
        setTimeout(callback, deley_space * show_count++, array, m, n);
    }

    //初始化函数
    var init = function () {
        //实例化排序对象
        var arr = [];
        var number = Number(numberDom.value.trim());
        if (number !== NaN && number > 0) {
            arr = random(number, number, 1);
            showArr(arr);
        } else {
            arr = random(10, 100, 1);//随机生成待排序的数组
            //刷新显示初始数组
            showArr(arr);
        }
        arr = [2, 8, 7, 4, 1, 5];
        console.log("待排序的数组", arr);
        showArr(arr);

        //随机生成指定长度的数组
        getArrDom.addEventListener("click", function () {
            if (animation_flag === true) {
                return;
            }
            var number = Number(numberDom.value.trim());
            if (number !== NaN && number > 0) {
                arr = random(number, number, 1);
                console.log("随机生成的数组：", arr);
                showArr(arr);
            } else {
                alert("请输入正确的数组长度");
            }
        });
        //点击开始排序
        button.addEventListener("click", function () {
            //在动画中点击无效
            if (animation_flag === true) {
                return;
            }
            deley_space = Number(deleyDom.value.trim());//输入的动画时间间隔，控制动画快慢(单位ms)
            var order = orderSelect.selectedIndex === 0 ? false : true;//选择的排序顺序
            var index = select.selectedIndex;//选择的排序方法
            var traversalArr = [];
            //按选择的排序方式和顺序排序
            switch (index) {
                case 0: traversalArr = shellSort(arr, order, showSort);
                    console.log("希尔排序:", traversalArr);
                    break;
                default: //alert("选择遍历方式出错");
                    break;
            }
        });
    }

    //希尔排序
    var shellSort = function (arr, type, showSort) {
        //输入检测
        if (!isArray(arr)) {
            throw Error("the input of bubbleSort is not a array");
            return;
        }
        //深拷贝，不改动输入数组
        var out = [];
        for (let i = 0; i < arr.length; i++) {
            out[i] = arr[i];
        }
        //order==false为升序，否则为降序
        var order = type !== true ? 1 : -1;
        var half = parseInt(out.length / 2);
        for (let d = half; d >= 1; d = parseInt(d / 2)) {
            for (let i = d; i < out.length; i++) {
                for (let j = i - d; j >= 0; j -= d) {
                    if (typeof showSort === "function") {
                        showSort(out, j, j + d);
                    }
                    if (order * out[j + d] < order * out[j]) {
                        let tem = out[j + d];
                        out[j + d] = out[j];
                        out[j] = tem;
                    }
                }
            }
        }
        return out;
    }

    //判断是否为数组
    var isArray = function (arr) {
        if (Object.prototype.toString.call(arr) === "[object Array]") {
            return true;
        } else {
            return false;
        }
    }

    //初始化
    init();
})()